(* ast.sml --- 
 * 
 * Filename: ast.sml
 * Description:  Abstract Syntax Tree of our C language
 *)

(* Code: *)

structure Ast = struct 

type pos = int
type id  = string * pos 

datatype UniOp = 
	 (* -x *)
	 Neg of pos
       (* if(!x) *)
       | Not of pos

datatype BinOp =
	 (* + - * / *)
	 Add of pos
       | Sub of pos
       | Mul of pos
       | Div of pos

datatype LogicOp =
	 (* && || *)
	 And of pos
       | Or of pos

datatype RelOp=
	 (* == != > >= < <= *)
	 Eq of pos
       | Ne of pos
       | Gt of pos
       | Ge of pos
       | Lt of pos
       | Le of pos

(* types *)
datatype Type 
  (* int  *)
  = Int of pos
  (* char *)
  | Char of pos
  (* void *)
  | Void of pos
  (* struct id *)
  | StructType of id * pos
  (* type* *)
  | Pointer of Type * pos
  (* type[num] *)
  | Array of int * Type * pos


(* expressions *)
datatype Exp
  (* -e !e *)
  = UniOpExp of Exp * UniOp * pos
  (* e+e e-e ... *)
  | BinOpExp of Exp * BinOp * Exp * pos
  (* e&&e ... *)
  | LogicOpExp of Exp * LogicOp * Exp * pos
  (* e>e ... *)
  | RelOpExp of Exp * RelOp * Exp * pos
  (* call a function: id(parameter,parameter...) *)
  | FunCall of id * (Exp list) * pos
  (* parened exp e.g. (x+1) *)
  | Paren of Exp * pos
  (* L-value *)
  | LvalExp of Lval * pos
and Lval 
  (* id *)
  = Ident of id * pos
  (* id.field *)
  | Dot of Lval * string * pos
  (* *id *)
  | Star of Lval * pos
  (* id->field *)
  | Pto of Lval * string * pos
  (* id[num] *)
  | Index of Lval * Exp * pos

(* declare a variable *)
(* int a; *)
type VarDecl= Type * id * pos 

(* Statements *)
datatype Stm
  (* if *)
  = If of Exp * BlockType * BlockType * pos
  (* while *)
  | While of Exp * BlockType * pos 
  (* return exp *)
  | Return of Exp * pos 
  (* return; *)
  | ReturnNull of pos
  (* for(stm;exp;stm) block *)
  | For of Stm * Exp * Stm * BlockType * pos 
  (* exp e.g.  x+1; func(x); *)
  | ExpStm of Exp * pos
  (* lval = exp  *)
  | Assign of Lval * Exp * pos
  (* block e.g. {int x;return x;} *)
  | BlockStm of BlockType * pos
and BlockType 
  = Block of (VarDecl list) * (Stm list) * pos 

(* only Type of the function(without block) *)
type FunctionProto = Type * id * VarDecl list * pos 

(* function *)
(* int main(int x) {return x;} *)
(* Type id  VarDecl list Block *)
type Function = FunctionProto * BlockType * pos



(* struct *)
(* struct test{int x;int y;} *)
(*        id  VarDecl list   *)
type Struct = id * (VarDecl list) * pos 

(* A program contains FunctionProtos, Structs and Functions *)

(* !!!ATTENTION!!! *)
(* Your Yacc File Should return a value with P *)
type Program = 
	 FunctionProto list * Struct list * Function list 


end

(* ast.sml ends here *)
